// 这是洛谷模板题P3690的代码
#include <bits/stdc++.h>
using namespace std;

const int R = 1e5 + 10;
class LCT
{
public:
	struct
	{
		int org, res, son[2], fa;
		bool tag;
	} t[R];
	// 以下为splay操作
#define lc(k) t[k].son[0]
#define rc(k) t[k].son[1]
#define fa(k) t[k].fa
#define isrc(k) (rc(fa(k)) == k)
#define reverse(k) swap(lc(k), rc(k)), t[k].tag ^= 1
#define notroot(k) (lc(fa(k)) == k || rc(fa(k)) == k) // 只要它是一个父亲的子结点，那它就不是根
#define connect(x, f, k) fa(x) = f, t[f].son[k] = x
	void pushup(int k)
	{
		t[k].res = (t[k].org ^ t[lc(k)].res ^ t[rc(k)].res);
	}
	void pushdown(int k)
	{
		if (t[k].tag)
		{
			reverse(lc(k));
			reverse(rc(k));
			t[k].tag = false;
		}
	}
	void pushdown_all(int x)
	{
		if (notroot(x))
		{
			pushdown_all(fa(x));
		}
		pushdown(x);
	}
	void rotate(int x)
	{
		int f = fa(x), ff = fa(f), k = isrc(x);
		fa(x) = ff;
		if (notroot(f))
			t[ff].son[isrc(f)] = x;
		connect(t[x].son[k ^ 1], f, k);
		connect(f, x, k ^ 1);
		pushup(f), pushup(x);
	}
	void splay(int x)
	{
		pushdown_all(x);
		int f;
		while (notroot(x))
		{
			f = fa(x);
			if (notroot(f))
            {
				isrc(x) ^ isrc(f) ? rotate(x) : rotate(f);
            }
			rotate(x);
		}
	}
	// 以下为LCT操作
	void access(int x)
	{
		for (int y = 0; x; y = x, x = fa(x))
		{
			splay(x);
			rc(x) = y;
			pushup(x);
		}
	}
	void makeroot(int x)
	{
		access(x);
		splay(x);
		reverse(x);
	}
	int findroot(int x)
	{
		access(x);
		splay(x);
		while (lc(x))
		{
			pushdown(x);
			x = lc(x);
		}
		splay(x);
		return x;
	}
	void link(int x, int y)
	{
		makeroot(x);
		if (findroot(y) == x)
		{
			return;
		}
		fa(x) = y;
	}
	void cut(int x, int y)
	{
		makeroot(x);
		if (findroot(y) != x || fa(y) != x || lc(y))
		{
			return;
		}
		rc(x) = fa(y) = 0;
		pushup(x);
		// 如果不加判断，需要将上面改成split(x, y), fa(x) = lc(y) = 0, pushup(y)
	}
	void split(int x, int y)
	{
		makeroot(x);
		access(y);
		splay(y);
	}
} lct;
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);
	int n, m, i, x, y, t;
	cin >> n >> m;
	for (i = 1; i <= n; ++i)
	{
		cin >> lct.t[i].org;
	}
	while (m--)
	{
		cin >> t >> x >> y;
		if (t == 0)
		{
			lct.split(x, y);
			cout << lct.t[y].res << '\n';
		}
		else if (t == 1)
		{
			lct.link(x, y);
		}
		else if (t == 2)
		{
			lct.cut(x, y);
		}
		else
		{
			lct.splay(x);
			lct.t[x].org = y;
			lct.pushup(x);
		}
	}
	return 0;
}
